#!/usr/bin/python3
# coding=utf-8

import win32com.client
import sys
import datetime
from check_log_grab.common import save_json
from loguru import logger as log


class ZkTecoReptile(object):
    def __init__(self, config: dict):
        """
        对象初始化
        :param config{
        ip_addr: 设备IP
        ,port: 设备端口
        ,title: 设备地点title
        ,detail: 设备地点详情
        }
        """
        self.ip = config.get("ip", "")
        self.port = config.get("port", 4370)
        self.title = config.get("title", "")
        self.detail = config.get("detail", "")
        self.zk = None
        self.ch_data = []

    def open_connect(self):
        """
        打开考勤机链接
        :return:
        """
        zk = win32com.client.Dispatch(r'zkemkeeper.ZKEM.1')
        if not zk.Connect_Net(self.ip, self.port):
            log.error(f"device:{self.ip}, Connection failed！")
            sys.exit(1)
        log.info(f"device:{self.ip}, Connection successful！")
        self.zk = zk

    def close(self):
        """
        关闭打卡链接
        :return:
        """
        if self.zk is not None:
            self.zk.Disconnect()
            log.info(f"device:{self.ip}, Close Connection successful！")

    def __enter__(self):
        self.open_connect()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

    def get_userinfo(self):
        """
        下载考勤机上所有用户信息
        :return:dict
        """
        uid = {}
        if self.zk.ReadAllUserID(1):
            while 1:
                exists, id_num, username, other, privilege, enable = self.zk.GetAllUserInfo(1)
                if not exists:
                    break
                else:
                    if enable:
                        uid[id_num] = username
        return uid

    def load_all_date_data(self):
        """
        下载考勤机上所有打卡记录
        :return:[(id_num, timestamp, date(fmt),]
        """
        log.info("Start downloading CheckIn Data,Please wait....")
        if self.zk.ReadGeneralLogData(1):  # read All checkin data
            while 1:
                mach_num, id_num, verify_mode, out_mode, year, month, day, hour, minute, second, dwWorkCode, dwReserved = self.zk.GetGeneralExtLogData(
                    1)
                if not mach_num:
                    break
                self.ch_data.append({
                    "userid": id_num,
                    "checkin_time": int(datetime.datetime(year, month, day, hour, minute, second).timestamp()),
                    "groupname": "ZK",
                    "checkin_type": '',
                    "location_title": self.title,
                    "location_detail": self.detail,
                    "deviceid": self.ip,
                })
        log.info("downloading CheckIn Data successful！")

    def clear_all_log(self):
        """
        清除设备全部打卡数据
        :return:
        """
        return self.zk.ClearGLog()

    def save_check_file(self, chd, out_file=True):
        save_json(f"zk_{self.ip.replace('.', '-')}_{datetime.datetime.now().strftime('%Y%m%d %H%M%S')}.json",
                  chd, out_file=out_file)

    def get_check_in_data(self, u_ids, start=0, end=0, out_file=False):
        """
        获取数据
        :param u_ids
        :param start:
        :param end:
        :param out_file:
        :return:
        """
        if len(self.ch_data) == 0:
            self.load_all_date_data()
        if start == 0 and end == 0:
            self.save_check_file(self.ch_data, out_file=out_file)
            return self.ch_data
        else:
            result = []
            for row in self.ch_data:
                if start <= row['checkin_time'] <= end:
                    result.append(row)
            self.save_check_file(result, out_file=out_file)
            return result


if __name__ == '__main__':
    with ZkTecoReptile({"ip": "10.41.1.198"})as zkr:
        print(zkr.get_check_in_data([], out_file=True))
